package com.bungarus.sdk;

import com.bungarus.codec.protobuf.MessageProtobuf;
import com.bungarus.sdk.codec.ProtobufWrappedWithHttpReqEncoder;
import com.bungarus.sdk.codec.UnwrapHttpResp2ProtobufDecoder;
import com.bungarus.sdk.handler.ClientHandler;
import com.bungarus.sdk.handler.ClientHeartbeatHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpClientCodec;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.protobuf.ProtobufEncoder;
import io.netty.handler.timeout.IdleStateHandler;

import java.util.concurrent.TimeUnit;

/**
 * Created by tang on 2019/1/29.
 */
public class ClientChannelInitializer extends ChannelInitializer<SocketChannel> {
    private static final int ALL_IDLE_TIMEOUT = 4 * 60;

    private ClientHeartbeatHandler heartbeatHandler;
    private ClientHandler clientHandler;

    public ClientChannelInitializer(Client client) {
        heartbeatHandler = new ClientHeartbeatHandler();
        clientHandler = new ClientHandler(client);
    }

    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        initCodecHandlers(socketChannel);
        initNormalHandlers(socketChannel);
    }

    private void initNormalHandlers(SocketChannel socketChannel) {
        socketChannel.pipeline().addLast(new IdleStateHandler(0,
                0, ALL_IDLE_TIMEOUT, TimeUnit.SECONDS));
        socketChannel.pipeline().addLast(clientHandler);
        socketChannel.pipeline().addLast(heartbeatHandler);
    }

    /**
     * init handlers related to char codec
     * @param socketChannel socketChannel
     */
    private void initCodecHandlers(SocketChannel socketChannel) {
        socketChannel.pipeline().addLast(new HttpClientCodec());
        socketChannel.pipeline().addLast(new HttpObjectAggregator(1024*1024));
        socketChannel.pipeline().addLast(new UnwrapHttpResp2ProtobufDecoder(MessageProtobuf.Message.getDefaultInstance()));
        socketChannel.pipeline().addLast(new ProtobufWrappedWithHttpReqEncoder());
        socketChannel.pipeline().addLast(new ProtobufEncoder());
    }
}
